package org.lstt.ExcelReader;

import java.math.BigInteger;
import java.text.DateFormat;
import java.util.regex.Pattern;

import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.DateUtil;

/**
 * 对象单元格阅读器
 * 
 * @author tluo
 *
 */
public class ObjectCellReader implements CellReader<Object> {

	@Override
	public Object readCell(Cell cell) {
		if (null == cell) {
			return null;
		}
		switch (cell.getCellTypeEnum()) {
		case _NONE: // -1-未知类型
			return "Unknown";

		case NUMERIC: // 0-数值型
			return getValueOfNumericCell(cell);

		case STRING: // 1- 字符串型
			return cell.getStringCellValue();

		case FORMULA:// 2-公式型
			try {
				return getValueOfNumericCell(cell);
			} catch (IllegalStateException e) {
				try {
					return cell.getRichStringCellValue().toString();
				} catch (IllegalStateException e2) {
					return cell.getErrorCellValue();
				}
			} catch (Exception e) {
				e.printStackTrace();
			}

		case BLANK: // 3- 空值
			return "";

		case BOOLEAN:// 4- 布尔型
			return cell.getBooleanCellValue();

		case ERROR:// 5-错误
			return "Bad value!";

		default:
			return cell.getRichStringCellValue().getString();
		}
	}

	// 获取数字类型的cell值
	private static Object getValueOfNumericCell(Cell cell) {
		if (DateUtil.isCellDateFormatted(cell)) {
			return DateFormat.getDateTimeInstance().format(
					cell.getDateCellValue());
		} else {
			return getRealStringValueOfDouble(cell.getNumericCellValue());
		}
	}

	// 处理科学计数法与普通计数法的字符串显示，尽最大努力保持精度
	private static String getRealStringValueOfDouble(Double d) {
		String doubleStr = d.toString();
		boolean b = doubleStr.contains("E");
		int indexOfPoint = doubleStr.indexOf('.');
		if (b) {
			int indexOfE = doubleStr.indexOf('E');
			// 小数部分
			BigInteger xs = new BigInteger(doubleStr.substring(indexOfPoint
					+ BigInteger.ONE.intValue(), indexOfE));
			// 指数
			int pow = Integer.valueOf(doubleStr.substring(indexOfE
					+ BigInteger.ONE.intValue()));
			int xsLen = xs.toByteArray().length;
			int scale = xsLen - pow > 0 ? xsLen - pow : 0;
			doubleStr = String.format("%." + scale + "f", d);
		} else {
			java.util.regex.Pattern p = Pattern.compile(".0$");
			java.util.regex.Matcher m = p.matcher(doubleStr);
			if (m.find()) {
				doubleStr = doubleStr.replace(".0", "");
			}
		}
		return doubleStr;
	}

}
